<?php
namespace app\client\controller;
use app\common\lib\Redis;
use think\swoole\facade\Task;
use PhpParser\Node\Expr\AssignOp\Mod;

class Redenvelope extends Base {
    public function __construct() {
        parent::__construct();
    }
    
    public function officialLog() {
        $model = model('OfficialRedenvelopeLog');
        $today = date('Y-m-d 00:00:00', time());
        $today = strtotime($today);
        
        $where = 'day >=' . $today;
        
        $count = $model->where($where)->group('user_id')->count();
        $userList = $model->where($where)->group('user_id')->field('user_id')->order('id desc')->limit(10)->select()->toArray();
        
        $list = [];
        if(!empty($userList)) {
            $userIds = [];
            foreach ($userList as $user) {
                array_push($userIds, $user['user_id']);
            }
            
            $list = model('User')->findAll([['user_id', 'in', $userIds]], ['user_id', 'avatar']);
        }
        
        return successResult(['number_count' => $count, 'list' => $list]);
    }
    
    public function official() {
        $today = date('Y-m-d 00:00:00', time());
        $today = strtotime($today);
        
        $count = model('OfficialRedenvelopeLog')->where(['user_id' => $this->userid, 'day' => $today])->count();
        
        $list = [];
        for($i = 0; $i < (5 - $count); $i ++) {
            array_push($list, ['id' => $i, 'url' => '', 'amount' => mt_rand(1, 15) / 10, 'type' => 4]);
        }
        
        return successResult(['list' => $list]);
    }
    
    public function grabOfficial() {
        $userId = $this->userid;
        $time = time();
        $today = date('Y-m-d 00:00:00', $time);
        $today = strtotime($today);
        
        $model = model('OfficialRedenvelopeLog');
        $walletModel = model('UserWallet');
        $model->startTrans();
        
        try {
            $wallet = $walletModel->where(['user_id' => $userId])->field(['amount', 'redenvelope_amount'])->lock(true)->find();
            if(empty($wallet)) {
                $model->rollback();
                return errorResult('ss');
            }
            
            $wallet = $wallet->toArray();
            
            $count = $model->where(['user_id' => $userId, 'day' => $today])->count();
            if($count >= 5) {
                $model->rollback();
                return errorResult();
            }
            
            $amount = mt_rand(1, 6) / 100;
            
            $rs = $walletModel->modify(['user_id' => $userId], ['amount' => $wallet['amount'] + $amount, 'redenvelope_amount' => $wallet['redenvelope_amount'] + $amount]);
            if(!$rs) {
                $model->rollback();
                return errorResult();
            }
            
            $id = $model->add(['user_id' => $userId, 'amount' => $amount, 'day' => $today, 'add_time' => $time]);
            if(!$id) {
                $model->rollback();
                return errorResult();
            }
            
            $rs = model('UserFinanceLog')->add(['user_id' => $userId, 'before_amount' => $wallet['amount'], 'amount' => $amount, 'type' => 3, 'related_id' => $id, 'add_time' => $time]);
            if(!$rs) {
                $model->rollback();
                return errorResult();
            }
            
            $rs = model('RedenvelopeReceiveLog')->add(['user_id' => $userId, 'type' => 3, 'amount' => $amount, 'add_time' => $time]);
            if(!$rs) {
                $model->rollback();
                return errorResult();
            }
            
            $model->commit();
            return successResult(['amount' => $amount]);
            
        } catch (\Exception $e) {
            $model->rollback();
            return errorResult();
        }
        
        
    }
    
    /**
     * 附近的红包
     * 附近红包拿出来的是数据结构是 $chatId . ',' .$chatRedenvelopeId . $userId
     * **/
    
    public function near() {
        $params = request()->get();
        
        $lng = isset($params['longitude']) ? floatval($params['longitude']) : 114.085947;
        $lat = isset($params['latitude']) ? floatval($params['latitude']) : 22.547;
        
        unset($params);

        $redis = new Redis();
        
        $geos = $redis->handler()->geoRadius('near_redenvelope', $lng, $lat, 3000 ,'m' , ['ASC', 'WITHDIST']);
        
        $chatList = $this->_handler($geos, $redis, 1);
        
        return successResult(['list' => $chatList]);
    }
    
    
    
    public function city() {
        $cityId = request()->get('cityId', 0, 'intval');
        if($cityId <= 0){
            return errorResult();
        }
        
        $redis = new Redis();
        
        $result = $redis->sRandMember('redenvelope_city_' . $cityId, 20);
        
        $chatList = $this->_handler($result, $redis, 2);
        
        return successResult(['list' => $chatList]);
        
    }
    
    public function country() {
        $redis = new Redis();
        
        $result = $redis->sRandMember('redenvelope_country', 20);
        
        $chatList = $this->_handler($result, $redis, 2);
        
        return successResult(['list' => $chatList]);
    }
    
    
    private function _handler($result, &$redis, $type) {
        $chatList = [];
        try {
            $userId = $this->userid;
            $redenvelopes = []; //红包
            if(!empty($result)){
                $chatIds = [];
                foreach($result as $item){
                    $item = $type == 1 ? explode(',', $item[0]) : explode(',', $item);
                    array_push($redenvelopes , ['chat_id' => $item[0], 'chat_redenvelope_id' => $item[1], 'user_id' => $item[2]]);//
                    if($userId != $item[2]){ //不是自己的红包
                        //array_push($chatIds, $item[0]);
                    }
                    
                    array_push($chatIds, $item[0]);
                }
                
                if(!empty($chatIds)) { //查询领取过的红包
                    //已经领取过的红包
                    $hadReceiveList = model('ChatRedenvelopeReceiveLog')->findAll(['user_id' => $userId, 'chat_id' => $chatIds], ['chat_id']);
                    if($hadReceiveList) {
                        foreach ($hadReceiveList as $k => $v) {
                            $hadReceiveList[$k] = $v['chat_id']; //把已经领取过的红包转成 [1,2,4,5,6]格式
                        }
                        
                        //剔除领过的红包
                        foreach($redenvelopes as $k => $item) {
                            if(in_array($item['chat_id'], $hadReceiveList)) {
                                unset($redenvelopes[$k]);
                            }
                        }
                    }
                    unset($hadReceiveList);
                }
                
                $chatIds = [];
                $userIds = [];
                foreach($redenvelopes as $redenvelope) {
                    array_push($chatIds, 'chat_' . $redenvelope['chat_id']);
                    if(!in_array($redenvelope['user_id'], $userIds)){
                        array_push($userIds, 'user_' . $redenvelope['user_id']);
                    }
                }
                $userResult = $redis->mget($userIds);
                $userList = [];
                foreach($userIds as $k => $id){
                    if($userResult[$k]){
                        $user = json_decode($userResult[$k], true);
                        $userList['user_' . $user['user_id']] = $user;
                    }
                }

                $chatResult = $redis->mget($chatIds);
                $redis->close();
                if($chatResult){
                    foreach ($chatResult as &$item) {
                        if(!$item){
                            continue;
                        }
                        $item = json_decode($item, true);
                        if($userId == $item['user_id']){
                            $item['self'] = true;
                        }else{
                            $item['self'] = false;
                        }
                        
                        $item['user'] = $userList['user_' . $item['user_id']];
                        
                        unset($item['user_id']);
                        
                        array_push($chatList, $item);
                    }
                }
                
            }
        } catch (\Exception $e) {
           $redis->close();
       }
        
        return $chatList;
    }
    
    public function redenvelope() {
    $id = request()->get('id', 0, 'intval');
        if($id <= 0){
            return errorResult();
        }
        
        $redis = new Redis();
        
        try {
        	$chat = $redis->get('chat_' . $id);
        	
        	if(empty($chat)){
        		$chat = model('Chat')->findOne(['chat_id' => $id], ['content', 'picture', 'user_id', 'location', 'longitude', 'latitude', 'create_time']);
        		if(empty($chat)){
        			return errorResult('记录已被删除', 404);
        		}
        		$chat['picture'] = json_decode($chat['picture'], true);
        	}else{
        		$chat = json_decode($chat, true);
        	}
        	
        	//查看是否收藏了
        	$collectId = model('ChatCollect')->where(['user_id' => $this->userid, 'chat_id' => $id])->value('id');
        	$chat['collectStatus'] = $collectId === null ? false : true;
        	
        	$chat['user'] = $redis->get('user_' . $chat['user_id']);
        	
        	$redis->close();
        	
        	return successResult($chat);
        } catch (\Exception $e) {
        	$redis->close();
        	return errorResult();
        }
    }
    
    public function receiveView (){
    	$id = request()->get('id', 0, 'intval');
    	if($id <= 0){
    		return errorResult();
    	}
    	
    	$quantity = model('ChatRedenvelope')->where(['chat_id' => $id])->value('receive_quantity');
    	if($quantity === null){
    		return errorResult();
    	}
    	
    	$userList = [];
    	
    	if($quantity > 0){
    		$list = model('ChatRedenvelopeReceiveLog')->where(['chat_id' => $id])->field('user_id')->limit(10)->select()->toArray();
    		$userIds = [];
    		foreach ($list as $v) {
    			 array_push($userIds, 'user_' . $v['user_id']);
    		}
    		
    		$redis = new Redis();
    		
    		try {
    			$userList = $redis->mget($userIds);
    		} catch (\Exception $e) {
    			
    		}
    		$redis->close();

    	}
    	
    	return successResult(['quantity' => $quantity, 'list' => $userList]);
    }
    
    //抢红包
    public function grab() {
    	$chatId = request()->get('id', 0, 'intval');
    	
    	if($chatId <= 0){
    		return errorResult('a');
    	}
    	
    	$userId = $this->userid;
    	
    	//查看有无领取过
    	$receiveLogModel = model('ChatRedenvelopeReceiveLog');
    	$receiveLog = $receiveLogModel->findOne(['user_id' => $userId, 'chat_id' => $chatId], ['amount']);
    	if(!empty($receiveLog)){
    		return successResult(['amount' => $receiveLog['amount']]);
    	}
    	
    	$redis = new Redis();
    	$amount = $redis->handler()->lPop('redenvelope__list_' . $chatId); //抢到的红包金额
    	
    	if($amount === false){
    		/* $chatRedenvelopeId = model('ChatRedenvelope')->where(['chat_id' => $chatId])->value('id');
    		$redis->handler()->zRem('near_redenvelope', $chatId . ',' . $chatRedenvelopeId . ',' . $userId);
    		$redis->close(); */
    		$redis->close();
    		return successResult(['amount' => 0]);
    	}
    	
    	$chat = $redis->get('chat_' . $chatId);
    	$redis->close();
    	
    	$chat = json_decode($chat, true);
    	
    	$walletModel = model('UserWallet');
    	
    	$walletModel->startTrans();
    	
    	try {
    	    $wallet = $walletModel->where(['user_id' => $userId])->field(['amount', 'redenvelope_amount'])->lock(true)->find();
    	    if(empty($wallet)) {
    	        $walletModel->rollback();
    	        return errorResult('b3333');
    	    }
    	    
    	    $wallet = $wallet->toArray();
    	    
    	    $rs = $walletModel->modify(['user_id' => $userId], ['amount' => $wallet['amount'] + $amount, 'redenvelope_amount' => $wallet['redenvelope_amount'] + $amount]);
    	    if(!$rs) {
    	        $walletModel->rollback();
    	        return errorResult('c');
    	    }
    		
    		$redenvelopeModel = model('ChatRedenvelope');
    		
    		$redenvelope = $redenvelopeModel->where(['chat_id' => $chatId])->field(['id', 'type', 'city_id', 'quantity', 'receive_quantity', 'receive_amount'])->lock(true)->find();
    		if(empty($redenvelope)) {
    			$walletModel->rollback();
    			$redis->close();
    			return errorResult('d');
    		}
    		
    		$redenvelope = $redenvelope->toArray();
    		$type = $redenvelope['type']; //类型，1：附近，2：城市，3：城市
    		$time = time();
    		
    		$updateData = ['receive_quantity' => $redenvelope['receive_quantity'] + 1, 'receive_amount' => $redenvelope['receive_amount'] + $amount];
    		if($updateData['receive_quantity'] == $redenvelope['quantity']) {
    			$updateData['status'] = 1;
    		}
    		
    		$rs = $redenvelopeModel->modify(['id' => $redenvelope['id']], $updateData);
    		if(!$rs) {
    			$walletModel->rollback();
    			$redis->close();
    			return errorResult('e');
    		}
    		
    		$rs = $receiveLogModel->add(['chat_id' => $chatId, 'chat_redenvelope_id' => $redenvelope['id'], 'user_id' => $userId, 'amount' => $amount, 'type' => $type, 'city_id' => $redenvelope['city_id'], 'add_time' => $time]);
    		if(!$rs) {
    			$walletModel->rollback();
    			$redis->close();
    			return errorResult('f');
    		}
    		
    		$rs = model('RedenvelopeReceiveLog')->add(['chat_id' => $chatId, 'user_id' => $userId, 'publisher' => $chat['user_id'], 'type' => 1, 'cover' => isset($chat['cover']) ? $chat['cover'] : '', 'content' => isset($chat['content']) ? substr($chat['content'], 0, 30) : '', 'amount' => $amount, 'add_time' => $time]);
    		if(!$rs) {
    		    $walletModel->rollback();
    		    $redis->close();
    		    return errorResult('1g');
    		}
    		
    		$rs = model('UserFinanceLog')->add(['user_id' => $userId, 'before_amount' => $wallet['amount'], 'amount' => $amount, 'type' => 1, 'related_id' => $chatId, 'add_time' => $time]);
    		if(!$rs) {
    			$walletModel->rollback();
    			$redis->close();
    			return errorResult('g');
    		}
    		
    		$walletModel->commit();
    		
    		if(isset($updateData['status']) && $updateData['status'] == 1){ //抢完了
    			
    			$key = $chatId . ',' . $redenvelope['id'] . ',' . $userId;
    			if($type == 1) {
    				$redis->handler()->zRem('near_redenvelope', $key);
    			}elseif($type == 2){
    				$redis->handler()->sRem('redenvelope_city_' . $redenvelope['city_id'], $key);
    			}else{
    				$redis->handler()->sRem('redenvelope_country', $key);
    			}
    		}
    		
    		$redis->close();
    		
    		return successResult(['amount' => $amount]);
    		
    	} catch (\Exception $e) {
    		$walletModel->rollback();
    		$redis->close();
    		return errorResult($e->getMessage());
    	}
    	
    	
    }
    
    public function redenvelopeNumber() {
        $model = model('RedenvelopeLog');
        $number = $model->where(['user_id' => $this->userid])->count();
        $amount = $model->where(['user_id' => $this->userid])->sum('amount');
        return successResult(['number' => $number, 'amount' => $amount]);
    }
    
    //红包发布记录
    public function redenvelopeLog() {
        $userId = $this->userid;
        $params = request()->get();
        $pk = isset($params['lastPk']) ? intval($params['lastPk']) : 0;
        $pageSize = isset($params['pageSize']) ? intval($params['pageSize']) : 20;
        
        $where = [['user_id', '=', $this->userid]];
        if($pk > 0) {
            $where[] = ['id', '<', $pk];
        }
        
        $list = model('RedenvelopeLog')->where($where)->order('id desc')->limit($pageSize)->select()->toArray();
        return successResult(['list' => $list]);
    }
    
    public function receiveNumber() {
        $number = model('RedenvelopeReceiveLog')->where(['user_id' => $this->userid])->count();
        $amount = model('UserWallet')->where(['user_id' => $this->userid])->value('redenvelope_amount');
        return successResult(['number' => $number, 'amount' => $amount]);
    }
    
    //红包领取记录
    public function receiveLog() {
        $userId = $this->userid;
        $params = request()->get();
        $pk = isset($params['lastPk']) ? intval($params['lastPk']) : 0;
        $pageSize = isset($params['pageSize']) ? intval($params['pageSize']) : 20;
        
        $where = [['user_id', '=', $this->userid]];
        if($pk > 0) {
            $where[] = ['id', '<', $pk];
        }
        
        $list = model('RedenvelopeReceiveLog')->where($where)->order('id desc')->limit($pageSize)->select()->toArray();
        if(!empty($list)) {
            $userIds = [];
            foreach ($list as $item) {
                if($item['type'] != 3) {
                    if(!in_array($item['publisher'], $userIds)) {
                        array_push($userIds, redisUserKey($item['publisher']));
                    }
                }
                
            }

            $redis = new Redis();
            $userList = $redis->mget($userIds);
            $redis->close();
            foreach ($list as &$item) {
                if($item['type'] != 3) {
                    foreach ($userList as &$user) {
                        if(!is_array($user)) {
                            $user = json_decode($user, true);
                        }
                        if($item['publisher'] == $user['user_id']) {
                            $item['avatar'] = $user['avatar'];
                        }
                    }
                }
                
            }
        }
        
        return successResult(['list' => $list]);
    }
    
}



















